import { Injectable } from "@nestjs/common";
import { InjectRepository } from "@nestjs/typeorm";
import { Role } from "./entities/role.entity";
import { Like, Repository } from "typeorm";

/**
 * @Injectable()：标记该类为一个可注入的服务
 * @InjectRepository(Role)：注入角色实体的 Repository，用于操作数据库
 * RoleRepository：TypeORM 提供的 Repository 对象，用于执行数据库操作
 */

@Injectable() 
export class RoleService {
    constructor(
        @InjectRepository(Role) // 注入角色的实体
        private readonly roleRepository:Repository<Role> // 针对于上一行Role数据库实体的实例
    ){}
    // 查询某个角色的信息
    findOne(id:number):Promise<Role | null> {
        return this.roleRepository.findOneBy({ id })
    }
    // 查询所有角色
    findAll(query):Promise<Role[]> {
        const where:any = {}
        if(query.name) {
            where.name = Like(`%${query.name}%`)
        }
        return this.roleRepository.find({
            where: where
        })
    }
    // 创建角色
    create(createRoleDto):Promise<Role> {
        return this.roleRepository.save(createRoleDto)
    }
    // 更新角色
    update(body) {
        if(body.id) {
            return this.roleRepository.update(body.id, body)
        }
    }
    // 删除角色
    async delete(id:string) {
        console.log(id);
        // 1. 删除与之关联的menu表的meta的角色绑定的信息以及中间表role_menu的关联信息
        await this.delMenuListRole(id)
        // 2. 删除与之关联的user表的角色绑定的信息
        await this.delUserListRole(id)
        // 3. 删除中间表role_permission相关联的角色绑定的信息
        await this.delPermissionListRole(id)
        // 4. 删除角色表的该角色信息
        return this.roleRepository.delete(id)
    }
    // 根据角色ID绑定菜单和操作权限
    async bindRoleMenuAndPermission(body) {
        const { roleId, menuIds, permissionIds } = body
        
        const searchMenuRoleSQL = `select * from role_menu where roleId = ${roleId}`
        // 先查询该角色id是否已经有菜单信息，判断是新增还是更新
        const res = await this.roleRepository.query(searchMenuRoleSQL)
        if(res.length > 0) {
            // 删除
            await this.delMenuListRole(roleId)
        }
        const searchPermissionRoleSQL = `select * from role_permission where roleId = ${roleId}`

        // 先查询该角色id是否已经有权限信息，判断是新增还是更新
        const res2 = await this.roleRepository.query(searchPermissionRoleSQL)
        if(res2.length > 0) {
            // 删除
            await this.delPermissionListRole(roleId)
        }
        // 更新菜单
        if(menuIds.length > 0) {
            // 再批量插入
            for (const menuId of menuIds) {
                const updateSQL = `insert into role_menu(roleId, menuId) values(${roleId}, ${menuId})`
                await this.roleRepository.query(updateSQL)
                // 处理该菜单表的元数据的角色role的拼接以及更新菜单
                await this.getRoleStringArr(menuId, roleId)
            }
        }
        // 更新权限
        if(permissionIds.length > 0) {
            // 再批量插入
            for (const permissionId of permissionIds) {
                const updateSQL = `insert into role_permission(roleId, permissionId) values(${roleId}, ${permissionId})`
                await this.roleRepository.query(updateSQL)
            }
        }
        return true;
    }
    async delMenuListRole(roleId) {
        // 删除1：如果是更新则先一步把它的角色管理的菜单信息删除
        const delSQL = `delete from role_menu where roleId = ${roleId}`
        await this.roleRepository.query(delSQL)
        // 删除2：删除所有菜单的meta的roleId
        // 获取所有角色列表
        const res =  await this.roleRepository.find()
        let roleName = ""
        res.forEach((item) => {
            if(item.id == roleId) {
                roleName = item.name
            }
        })
        const searchMenuSQL = `select * from menu`
        const menuRes = await this.roleRepository.query(searchMenuSQL)
        menuRes.forEach(async (item) => {
            if(item.meta) {
                let meta = JSON.parse(item.meta)
                if(meta.roles && meta.roles.length > 0) {
                    meta.roles = meta.roles.filter((item) => item != roleName)
                    meta = JSON.stringify(meta)
                    const updateMenuSQL = `update menu set meta = '${meta}' where id = ${item.id}`
                    await this.roleRepository.query(updateMenuSQL)
                }
            }
        })
    }
    async delPermissionListRole(roleId) {
        // 删除1：如果是更新则先一步把它的角色管理的菜单信息删除
        const delSQL = `delete from role_permission where roleId = ${roleId}`
        await this.roleRepository.query(delSQL)
    }
    async delUserListRole(roleId) {
        // 先找到该角色的名称
        const res = await this.roleRepository.find()
        let roleName = ""
        res.forEach((item) => {
            if(item.id == roleId) {
                roleName = item.name
            }
        })
        // 查询用户表
        const searchUserSQL = `select * from admin_user`
        const userRes = await this.roleRepository.query(searchUserSQL)
        userRes.forEach(async (item) => {
            if(item.role.includes(roleName)) {
                item.role = JSON.parse(item.role).filter((i) => i !== roleName)
                item.role = JSON.stringify(item.role)
                const updateUserSQL = `update admin_user set role = '${item.role}' where id = ${item.id}`
                await this.roleRepository.query(updateUserSQL)
            }
        })
    }
    async getRoleStringArr(menuId,roleId) {
        // 获取所有角色列表
        const res =  await this.roleRepository.find()
        
        if(res.length > 0) {
            const roleNameArr:any[] = []
            res.forEach((item) => {
                if(item.id == roleId) {
                    roleNameArr.push(item.name)
                }
            })
            const metaArr = roleNameArr.map((meta) => meta?.replaceAll('"', '\\"'));

            const searchMenuSQL = `select * from menu where id = ${menuId}`
            const menuRes = await this.roleRepository.query(searchMenuSQL)
            
            let meta = JSON.parse(menuRes[0].meta)
            
            if(meta.roles && meta.roles.length > 0) {
                meta.roles = [...meta.roles, ...metaArr]
                meta.roles = Array.from(new Set(meta.roles))
            } else {
                meta.roles = metaArr
            }
            meta = JSON.stringify(meta)
            console.log(meta);
            
            const updateMenuSQL = `update menu set meta = '${meta}' where id = ${menuId}`
            await this.roleRepository.query(updateMenuSQL)
        }
    }
    // 查询角色的菜单信息
    findRoleMenu(roleId) {
        if(roleId) {
            const sql = `select menuId  from role_menu where roleId = ${roleId}`
            return this.roleRepository.query(sql)
        } else {
            return Promise.resolve([])
        }
    }
    // 查询角色的权限信息
    findRolePermission(roleId) {
        if(roleId) {
            const sql = `select permissionId  from role_permission where roleId = ${roleId}`
            return this.roleRepository.query(sql)
        } else {
            return Promise.resolve([])
        }
    }
}